extends Node

# 用户自定义指令
func userParse(code : String, params : Array, info : Dictionary):
	match params[0]:
		"tologo":
			Worker.toLogo()
		_:
			if params.size() == 2:
				# 由2个参数组成的字符串,默认当做 [名字] [对白] 进行处理
				name(params[0])
				speak(params[1])
				return
			elif params.size() == 1:
				# 一个参数默认当做 [对白] 进行处理
				speak(params[0])
				return
			print("[{name} 第{line}行]未注册的指令: '{code}'".format({
					"name": info.fileName,
					"line": info.lineNum,
					"code": code
				}))
	pass

# 标准指令
func parse(code : String, info : Dictionary):
	var params = code.split(" ")
	if params.size() == 0:
		return
	match params[0]:
		"print":
			print(params[1])
		"run":
			run(params[1])
		"jump":
			jump(params[1])
		"exit":
			exit()
		"goto":
			goto(params[1])
		"pause":
			pause(params[1].to_int())
		"text":
			params = code.split(" ", true, 2)
			if params.size() == 2:
				speak(params[1])
			elif params.size() == 3:
				name(params[1])
				speak(params[2])
		"bg":
			if params.size() == 2:
				bgonly(0, params[1])
			elif params.size() == 3:
				bg(0, params[1], 1, params[2].to_int())
			elif params.size() == 5:
				# 兼容模式: bg(0, 'x.jpg', 1, 1000)
				bg(0, params[2], params[3].to_int(), params[4].to_int())
			else:
				_parseError('bg', code, info)
		"bgxy":
			bgxy(0, params[1].to_float(), params[2].to_float())
		"bgeff":
			bgeff(0, params[1].to_int(), params[2].to_int(), params)
		"bgon":
			bgon(0)
		"bgoff":
			bgoff(0)
		"bgnull":
			bgnull(0)
		"fg":
			if params.size() == 3:
				fgonly(params[1].to_int(), params[2])
			elif params.size() == 4:
				fg(params[1].to_int(), params[2], 1, params[3].to_int())
			elif params.size() == 5:
				# 兼容模式: fg(0, 'x.jpg', 1, 1000)
				fg(params[1].to_int(), params[2], params[3].to_int(), params[4].to_int())
			else:
				_parseError('fg', code, info)
		"fgxy":
			fgxy(params[1].to_int(), params[2].to_float(), params[3].to_float())
		"fgeff":
			fgeff(params[1].to_int(), params[2].to_int(), params[3].to_int(), params)
		"fgon":
			fgon(params[1].to_int())
		"fgoff":
			fgoff(params[1].to_int())
		"fgnull":
			fgnull(params[1].to_int())
		"msgboxon":
			msgboxon(params[1].to_int())
		"msgboxoff":
			msgboxoff(params[1].to_int())
		"choice":
			var arr = Array(params)
			choice(arr.slice(1, -1))
		_:
			userParse(code, params, info)
			
func _parseError(key : String, code : String, info : Dictionary):
	print('[{name} 第{line}行] {key} 指令参数不合法: {code}'.format({
		"key": key,
		"name": info.fileName,
		"line": info.lineNum,
		"code": code
	}))
	
func run(name : String):
	Model.play.addStory(name)
	pass
	
func jump(name : String):
	exit()
	run(name)
	pass

func exit():
	Model.play.popStory()
	pass
	
func goto(name : String):
	Model.play.seekStory(name)
	pass
	
func pause(ms : int):
	Model.play.pauseStory(ms)
	pass
	
func allclear():
	Model.play.layer.resetAllSlot()
	Model.dialog.setName('')
	Model.dialog.setText('')
	Model.dialog.visible = false
	Model.select.clear()
	Audio.stop()
	pass

func bg(index : int, fileName : String, effectId : int, ms : int):
	bgonly(index, fileName)
	bgeff(index, effectId, ms, [])
	pass
	
func bgonly(index : int, fileName : String):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	_bg.loadImage("res://game/" + fileName)
	pass
	
func bgxy(index : int, x : float, y : float):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	_bg.setPosition(Vector2(x, y))
	pass
	
func bgeff(index : int, effectId : int, ms : int, params : Array):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	match effectId:
		4:
			_bg.moveBy(Vector2(params[3].to_float(), params[4].to_float()), ms)
		5:
			if params.size() == 4:
				params.append(params[3])
			_bg.scaleTo(Vector2(params[3].to_float(), params[4].to_float()), ms)
		6:
			_bg.rotateBy(params[3].to_float(), ms)
		_:
			_bg.setEffect(effectId, ms)
	pass
	
func bgon(index : int):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	_bg.setVisible(true)
	pass
	
func bgoff(index : int):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	_bg.setVisible(false)
	pass
	
func bgnull(index : int):
	if index != 0:
		return
	var _bg = Model.play.layer.getSlot(index)
	_bg.nullImage()
	pass

func fg(index : int, fileName : String, effectId : int, ms : int):
	fgonly(index, fileName)
	fgeff(index, effectId, ms, [])
	pass
	
func fgonly(index : int, fileName : String):
	var offset = 1
	Model.play.layer.setSlot(index + offset, "sprite")
	var _fg = Model.play.layer.getSlot(index + offset)
	_fg.loadImage("res://game/" + fileName)
	pass
	
func fgxy(index : int, x : float, y : float):
	var offset = 1
	var _fg = Model.play.layer.getSlot(index + offset)
	_fg.setPosition(Vector2(x, y))
	pass
	
func fgeff(index : int, effectId : int, ms : int, params : Array):
	var offset = 1
	var _fg = Model.play.layer.getSlot(index + offset)
	match effectId:
		4:
			_fg.moveBy(Vector2(params[4].to_float(), params[5].to_float()), ms)
		5:
			if params.size() == 5:
				params.append(params[4])
			_fg.scaleTo(Vector2(params[4].to_float(), params[5].to_float()), ms)
		6:
			_fg.rotateBy(params[4].to_float(), ms)
		_:
			_fg.setEffect(effectId, ms)
	pass
	
func fgon(index : int):
	var offset = 1
	var _fg = Model.play.layer.getSlot(index + offset)
	_fg.setVisible(true)
	pass
	
func fgoff(index : int):
	var offset = 1
	var _fg = Model.play.layer.getSlot(index + offset)
	_fg.setVisible(false)
	pass
	
func fgnull(index : int):
	var offset = 1
	var _fg = Model.play.layer.getSlot(index + offset)
	_fg.nullImage()
	pass
	
func name(v : String):
	Model.dialog.setName(v)
		
func speak(v : String):
	Model.dialog.setText(v)
	
func msgboxon(ms : int):
	Model.dialog.fadeIn(ms)
	pass
	
func msgboxoff(ms : int):
	Model.dialog.fadeOut(ms)
	pass
	
func choice(params : Array):
	var arr = []
	for i in range(0, params.size(), 2):
		arr.append({
			"title": params[i],
			"tag": params[i+1]
		})
	Model.select.setSelects(arr)
